home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / games / 65 / pascal / whereis.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1986-10-16  |  12.0 KB  |  378 lines

  1. {===========================================================================
  2.  
  3.                                WHEREIS.TOS
  4.  
  5.         Copyright (c) 1986 by Keith Ledbetter and Orion Micro Systems
  6.  
  7.             To be given away and used by anyone who wants it!
  8.  
  9.  
  10.   Note:  If executing this module from the desktop, you should still name
  11.          it .TOS, not .TTP.  If no parameters are present on the command
  12.          line, the program assumes that it was executed from the desktop
  13.          and will prompt you for the search mask, and will also prompt you
  14.          to 'press return' after the command is executed (so you won't
  15.          flash back to gem before your eyes get focused!).
  16.  
  17.  ----------------------------------------------------------------------------
  18.  
  19.   Program WhereIS: searches all subdirectories and displays any filename
  20.                    that matches the given filemask.  If no drive is given,
  21.                    then the search occurs on the default drive.  If no
  22.                    subdirectory is given, then the search begins with the
  23.                    current default directory and goes downward.
  24.  
  25.   Program Usage:  Is really written for a "command shell" environment, but
  26.                   can be executed from the desktop if given an extender
  27.                   of .TOS  (see above).  Has been tested extensively
  28.                   (1 day.....[just kidding!!]) under DOS-Shell and GEM.
  29.  
  30.   Program Notes:  WhereIS will build a table of all of the subdirectories
  31.                   on the disk from the current (or specified) path WITHOUT
  32.                   doing recursive-type calls.  This may be a tad bit
  33.                   slower, but it prevents a few "uglies" from popping up
  34.                   such as stack overflow, etc.  Once all of the path names
  35.                   are built into the table, WhereIS simply goes back thru
  36.                   the table and reads the directory of each path looking
  37.                   for matches on the user's input mask.
  38.  
  39.  
  40.   Some examples:
  41.   --------------
  42.  
  43.   whereis *.pas          will show all files with an extender of .PAS on the
  44.                          default drive, beginning the search with the default
  45.                          subdirectory.
  46.  
  47.   whereis \*.pas         will again show all files that have an extender of
  48.                          .PAS, but the search will begin at the ROOT (main)
  49.                          directory.  In other words, it will show any .PAS
  50.                          file on the ENTIRE disk.
  51.  
  52.   whereis b:\ab*.*       will show any file on diskette b: that begins with the
  53.                          letters "ab".
  54.  
  55.   whereis \whereis.pas   will show any file on the default drive that has the
  56.                          name WHEREIS.PAS.
  57.  
  58.   whereis c:\dir1\*.txt  will show any file on drive c, beginning in
  59.                          subdirectory \dir1\, that has an extender of .txt.
  60.  
  61.  
  62.     Now, who says you have to write everything useful in C ??  (heheh)
  63.  
  64.  ===========================================================================}
  65.  
  66.  
  67.  {$C-,D-,P-,R-,T-}                  { compiler directives }
  68.  
  69.  
  70. Program WhereIs;
  71.  
  72.  Const Copyright =
  73. '  WHEREIS v1.0 (FreeWare)  (c) 1986 by Keith Ledbetter / Orion Micro Systems';
  74.  
  75.  Type  Fmask = Packed Array [1..14] of Char;
  76.        TPath = Packed Array [1..80] of Char;
  77.        Str12 = String [12];
  78.  
  79.        Ftrec = Packed Record
  80.                   Dirnum: Byte;          { directory number          }
  81.                   Parent: Byte;          { parent directory's number }
  82.                   Name  : Str12;         { subdirectory name         }
  83.                End;
  84.  
  85.        Dtrec = Packed Record
  86.                   No_touch : Packed Array [0..19] of Byte;
  87.                   No_touch2: Byte;
  88.                   Attr     : Byte;
  89.                   T_Stamp  : Integer;
  90.                   D_Stamp  : Integer;
  91.                   Filesize : Long_Integer;
  92.                   Name     : Fmask;
  93.                End;
  94.  
  95.  
  96.   Var Inrec       : Dtrec;
  97.       Table       : Packed Array [1..255] of Ftrec;  { hold 255 directories }
  98.       CurPath     : TPath;
  99.       CurIdx      : Byte;                 { index into the table       }
  100.       CurParent   : Byte;                 { current parent path        }
  101.       X           : Integer;              { marks the spot...          }
  102.       Def_Drive   : String [80];          { where we are starting from }
  103.       Root_Path   : String [80];          { used as a work field       }
  104.       Search_Mask : String [80];          { what user wants us to find }
  105.       Temp        : String [80];
  106.       Pname       : Str12;
  107.       From_GEM    : Boolean;              { true if no parameters      }
  108.  
  109.  
  110.  {================================
  111.  
  112.     Some various GemDOS calls...
  113.  
  114.   ================================}
  115.  
  116.  Function Cur_Drive : Integer;
  117.     GemDOS( $19 ) ;
  118.  
  119.  Procedure Set_DTA (Var Buffer: Dtrec) ;
  120.     GemDOS( $1a ) ;
  121.  
  122.  Function Get_First (Var Path: TPath; Attr: Integer): Integer;
  123.     GemDOS( $4e ) ;
  124.  
  125.  Function Get_Next: Integer;
  126.     GemDOS( $4f ) ;
  127.  
  128.  
  129.  
  130.  {====================================================
  131.  
  132.     Build a string variable from the DTA buffer area
  133.  
  134.   ====================================================}
  135.  
  136.  Procedure Make_Fname (Var S: Str12);
  137.  
  138.   Var X: Integer;
  139.  
  140.    Begin
  141.      X := 1;
  142.      While (X <= 14) and (Inrec.Name [X] <> #0) do
  143.        begin
  144.          S [X] := Inrec.Name [X];
  145.          X := X + 1;
  146.        end;
  147.      S [0] := Chr (X - 1);
  148.    End;
  149.  
  150.  
  151.  
  152.  {====================================================
  153.  
  154.     Build the FULL path name of an entry from the
  155.     table by searching backwards in the table.
  156.  
  157.   ====================================================}
  158.  
  159.  Procedure Build_Mask (Pos: Integer);
  160.  
  161.  Var X: Integer;
  162.      H: Array [1..25] of Byte;          { holds indexes of paths      }
  163.      Z: Integer;
  164.  
  165.   Begin
  166.     Z := 0;                             { we must loop upwards in the }
  167.     Repeat                              { filename table, saving the  }
  168.       Z := Z + 1;                       { parents of this directory   }
  169.       H [Z] := Table [Pos].Dirnum;      { until we reach the root     }
  170.       Pos := Table [Pos].Parent;        { directory.                  }
  171.     Until Pos = 0;
  172.  
  173.     Root_Path := Def_Drive;             { now go thru and concat them }
  174.     Repeat
  175.       Root_Path := Concat (Root_Path, Table [H[Z]].Name, '\');
  176.       Z := Z - 1;
  177.     Until Z < 1;
  178.   End;
  179.  
  180.  
  181.  
  182.  
  183.  {====================================================
  184.  
  185.     This is the real workhorse.  It builds the table
  186.     entries of each subdirectory on the disk.
  187.  
  188.   ====================================================}
  189.  
  190.  Procedure Build_Subdir_Table;
  191.  
  192.   Var I, Tot : Integer;
  193.  
  194.   Begin
  195.      CurIdx := 1;
  196.      CurParent := 0;
  197.  
  198.      Tot := 0;
  199.      Set_DTA (Inrec);
  200.  
  201.      While Tot < CurIdx do
  202.        Begin
  203.          CurParent := Tot;
  204.          If Tot = 0 then
  205.            Root_Path := Def_Drive
  206.          Else
  207.            Build_Mask (Tot);
  208.          Temp := Concat (Root_Path, '*.*');
  209.          For I := 1 to Length (Temp) do
  210.            CurPath [I] := Temp [I] ;
  211.          CurPath [Length (Temp) + 1] := #0;
  212.          If Get_first (CurPath, $10 ) >= 0 Then
  213.            Repeat
  214.              With Inrec do
  215.                Begin
  216.                  If (Attr = $10) and (Name [1] <> '.') then
  217.                    Begin
  218.                      Table [CurIdx].Dirnum := CurIdx;
  219.                      Table [CurIdx].Parent := CurParent;
  220.                      Make_Fname (Table [CurIdx].Name);
  221.                      CurIdx := CurIdx + 1;
  222.                    End;
  223.                End;
  224.            Until Get_Next < 0 ;
  225.            Tot := Tot + 1;
  226.        End;
  227.   End;
  228.  
  229.  
  230.  
  231.  {====================================================
  232.  
  233.     Go through the table and search each subdirectory
  234.     for the requested filename.  If found, display it.
  235.  
  236.   ====================================================}
  237.  
  238.  Procedure Find_File;
  239.  
  240.   Var Tot, C, Z, I: Integer;
  241.       First: Boolean;
  242.  
  243.   Begin
  244.     Tot := 0;
  245.     Set_DTA (Inrec);
  246.     First := True;
  247.  
  248.     For Z := 0 to CurIdx - 1 do                   { do entire table    }
  249.       Begin
  250.         If Z = 0 then
  251.           Root_Path := Def_Drive
  252.         Else
  253.           Build_Mask (Z);
  254.         Temp := Concat (Root_Path, Search_Mask);
  255.         For I := 1 to Length (Temp) do
  256.           CurPath [I] := Temp [I] ;
  257.         CurPath [Length (Temp) + 1] := #0;
  258.         If Get_first (CurPath, 0) >= 0 Then       { found one!  }
  259.           Repeat
  260.             Make_Fname (Pname);
  261.             If First then
  262.               Begin
  263.                 Write (#13,#27,'K');
  264.                 First := False;
  265.               End;
  266.             Writeln ('     ',Root_Path, Pname);
  267.             Tot := Tot + 1;
  268.           Until Get_Next < 0 ;                    { get next one }
  269.       End;
  270.  
  271.     If Tot = 0 then
  272.       Writeln (#13,#27,'K',' No matches found.')
  273.     Else
  274.       Begin
  275.         Writeln;
  276.         If Tot = 1 then
  277.           Writeln (' 1 match found.')
  278.         Else
  279.           Writeln (' ',Tot,' matches found.');
  280.       End;
  281.  End;
  282.  
  283.  
  284.  
  285.  
  286.  {==================================
  287.  
  288.     Throw out a little help menu..
  289.  
  290.   ==================================}
  291.  
  292.  Procedure Help_Em_Out;
  293.  
  294.  Begin
  295.   Writeln (
  296.   '  Usage:  WHEREIS [a:\dir\]filemask.ext');
  297.   Writeln;
  298.   Writeln(
  299.   '   Desc:  WHEREIS will search downward from either the current drive/path');
  300.   Writeln(
  301.   '          or the specified drive/path looking for matches on the filename');
  302.   Writeln(
  303.   '          that you enter.  All matches will be displayed with their full');
  304.   Writeln(
  305.   '          pathname.  Primarily for hard disk users, it''s great for times');
  306.   Writeln(
  307.   '          you can''t quite remember where you put that file!');
  308.   Writeln(
  309.   '          Full wildcards are allowed in the search specifier.');
  310.  End;
  311.  
  312.  
  313.  
  314.  {===============================================
  315.  
  316.     Strip out the starting drive/path and the
  317.     search mask from the user's input line.
  318.  
  319.   ===============================================}
  320.  
  321.  Procedure Process_Cmd_Line;
  322.  
  323.   Var X: Integer;
  324.  
  325.   Begin
  326.     Def_Drive := Search_Mask;                 { plop it into defdrive  }
  327.     X := Length (Search_Mask);                { now, go backwards in   }
  328.     While (Search_Mask [X] <> '\') and        {  search_mask until we  }
  329.           (Search_Mask [X] <> ':') and        {  find the end of the   }
  330.           (X > 0) do                          {  path (if there is one)}
  331.         X := X - 1;
  332.     Def_Drive [0] := Chr (X);                 { set length byte        }
  333.     Delete (Search_Mask,1,Length(Def_Drive)); { remove path from search}
  334.     If Length (Search_Mask) = 0 then          { if no filename, do all }
  335.       Search_Mask := '*.*';                   {  (that'll teach em!)   }
  336.   End;
  337.  
  338.  
  339.  
  340.  
  341.  {===============================
  342.  
  343.      Main Control of WHEREIS
  344.  
  345.   ===============================}
  346.  
  347.  Begin
  348.  
  349.     Writeln;                            { our moment in the sun... }
  350.     Writeln (Copyright);
  351.     Writeln;
  352.  
  353.     From_GEM := False;                  { default to command line }
  354.  
  355.     Cmd_GetArg (1, Search_Mask);        { get filemask they want }
  356.  
  357.     If Length (Search_Mask) = 0 then    { nothing entered, so give }
  358.       Begin                             { them the help screen and }
  359.         Help_Em_Out;                    { prompt/get the search    }
  360.         From_GEM := True;               { mask.                    }
  361.         Writeln;
  362.         Write ('Search Mask => ');
  363.         Readln (Search_Mask);
  364.         Writeln;
  365.       End;
  366.  
  367.     Process_Cmd_Line;                   { strip out parms          }
  368.     Write (' Please Wait...');          { give us a second or two  }
  369.     Build_Subdir_Table;                 { generate the table       }
  370.     Find_File;                          { look for matches         }
  371.     If From_GEM then                    { if from GEM, let them    }
  372.       Begin                             { hit return.              }
  373.         Writeln;
  374.         Write ('Press RETURN...');
  375.         Readln (Search_Mask);
  376.       End;
  377.  End.
  378.